package cn.libinal.scloud.base.common.web;

import lombok.Data;
import lombok.Getter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分页请求参数
 *
 * @author libinal
 */
@Data
public class DataPageRequest {
    /**
     * 当前页面数
     */
    private Integer pageNumber = 1;
    /**
     * 每页条数
     */
    private Integer pageSize = 10;
    private List<OrderBy> orders = new ArrayList<>();

    private static Sort.Order apply(OrderBy orderBy) {
        if (DirectionEnum.DESC.getText().equalsIgnoreCase(orderBy.direction)) {
            return Sort.Order.desc(orderBy.getField());
        } else if (DirectionEnum.ASC.getText().equalsIgnoreCase(orderBy.direction)) {
            return Sort.Order.asc(orderBy.getField());
        } else {
            return Sort.Order.by(orderBy.getField());
        }
    }

    public PageRequest buildPageRequest() {
        // 当前页数不能小于1
        if (pageNumber < 1) {
            pageNumber = 1;
        }

        // 每页条数不能小于1
        if (pageSize < 1) {
            pageSize = 10;
        }

        if (orders.size() > 0) {
            List<Sort.Order> orderList = orders.stream()
                    .map(DataPageRequest::apply)
                    .collect(Collectors.toList());
            return PageRequest.of(pageNumber - 1, pageSize, Sort.by(orderList));
        }
        return PageRequest.of(pageNumber - 1, pageSize);
    }

    static DataPageRequest of(Pageable pageable) {
        DataPageRequest request = new DataPageRequest();
        request.setPageNumber(pageable.getPageNumber());
        request.setPageSize(pageable.getPageSize());
        if (pageable.getSort().isSorted()) {
            List<OrderBy> orderByList = pageable.getSort().stream()
                    .map(order -> OrderBy.of(order.getProperty(), order.getDirection().name()))
                    .collect(Collectors.toList());
            request.setOrders(orderByList);
        }

        return new DataPageRequest();
    }

    @Data
    private static class OrderBy {
        private String field;
        private String direction = DirectionEnum.DESC.getText();

        static OrderBy of(String field, String direction) {
            OrderBy orderBy = new OrderBy();
            orderBy.setField(field);
            orderBy.setDirection(direction);
            return orderBy;
        }
    }

    /**
     * 排序规则
     */
    @Getter
    private enum DirectionEnum {
        // 降序
        DESC("DESC"),
        // 升序
        ASC("ASC");

        /**
         * 内容
         */
        private String text;

        DirectionEnum(String text) {
            this.text = text;
        }
    }
}
